#ifndef APP_GLOBALS_DSTIN
#define APP_GLOBALS_DSTIN
#include <includes.h>

static void PORLocalRAMReset_DSTIN(void);
static void Init_DigitalInputsRawCloseSta(void);
static uint8_t DigitalInputsLayerHandle(OS_FLAGS os_value);
static uint8_t DigitalInputsWorkLayerHandle(OS_FLAGS os_value, uint8_t InputOrd, uint16_t *TiCount);

static uint8_t DigitalInputsScanLayerHandle(uint8_t InputOrd, uint16_t *TiCnt)
{
    uint16_t InputOldSta, InputNewSta;
    uint16_t InputBitOrd;
    /* Set Bit Order */
    InputBitOrd = 1 << InputOrd;                          // 通道号 变换为 位变量
    InputOldSta = DigitalInputsRawCloseSta & InputBitOrd; /* 获取当前通道的老状态，0:Open; 1:Close； DigitalInputsRawCloseSta 是所有输入端口的老状态，是全局变量 */

    /* Read Auxi Inputs */
    uint8_t InputPortSta = GPIO_ReadInputDataBit(DstInputsCfgTable[InputOrd].GPIOx, DstInputsCfgTable[InputOrd].GPIO_Pin);
    if(InputOrd==DstInputsOrd_EXCV2_HLIMIT || InputOrd==DstInputsOrd_EXCV2_LLIMIT)// 分压2特定逻辑处理
    {
        if (InputPortSta)    
            InputNewSta = 0; /* Inputs Open */
        else
            InputNewSta = InputBitOrd; /* Inputs Close */
    }
    else 
    {
        if (InputPortSta)
            InputNewSta = InputBitOrd; /* Inputs Close */
        else
            InputNewSta = 0; /* Inputs Open */
    }

    /* Check if Inputs Status changing 如果端口状态出现变化，则开始计时 */
    if (InputNewSta == InputOldSta)
        *TiCnt = 0;
    else
        (*TiCnt)++;

    if (*TiCnt < 3 ) // 如果端口状态改变的时间大于配置则清零，同时记录状态，且返回真值 150ms
        return (DEF_FALSE);

    *TiCnt = 0;
    /* Port new Sta */
    DigitalInputsRawCloseSta &= ~InputBitOrd;
    DigitalInputsRawCloseSta |= InputNewSta; /* 0:Open; 1:Close */

    return (DEF_TRUE);
}

/* Digital Inputs Action*/
static uint8_t DigitalInputsActionHandle(uint8_t InputOrd)
{
    uint16_t InputCurSta;
    uint16_t InputBitOrd;
    uint8_t InActiveSta, InAlarmType;
    uint8_t i;
    uint8_t OperaOpt=BitOperaOpt_Clr;

	/************************/
	/* Set Bit Order */
	InputBitOrd=1<<InputOrd;
	InputCurSta=DigitalInputsRawCloseSta&InputBitOrd;    /* 0:Open; 1:Close */

    if(InputCurSta)
    {
        InActiveSta=DEF_TRUE;
        OperaOpt = BitOperaOpt_Set;
    }
    
    switch (InputOrd)
    {
    case DstInputsOrd_EXCV2_HLIMIT:
        ModifyFlagShareBufferDataContent(NULL,CfgOperaType_None,FlagShareBuffer_RawAlarm,RawAlarm_DI_EXCV2_HLimit,OperaOpt);
        break;
    case DstInputsOrd_EXCV2_LLIMIT:
        ModifyFlagShareBufferDataContent(NULL,CfgOperaType_None,FlagShareBuffer_RawAlarm,RawAlarm_DI_EXCV2_LLimit,OperaOpt);
        break;
    case DstInputsOrd_BVOL_HLIMIT:
        ModifyFlagShareBufferDataContent(NULL,CfgOperaType_None,FlagShareBuffer_RawAlarm,RawAlarm_DI_BVOL_HLimit,OperaOpt);
        break;
    case DstInputsOrd_BVOL_LLIMIT:
        ModifyFlagShareBufferDataContent(NULL,CfgOperaType_None,FlagShareBuffer_RawAlarm,RawAlarm_DI_BVOL_LLimit,OperaOpt);
        break;
    case DstInputsOrd_EXCV_HLIMIT:
        ModifyFlagShareBufferDataContent(NULL,CfgOperaType_None,FlagShareBuffer_RawAlarm,RawAlarm_DI_EXCV_HLimit,OperaOpt);
        break;
    case DstInputsOrd_EXCV_LLIMIT:
        ModifyFlagShareBufferDataContent(NULL,CfgOperaType_None,FlagShareBuffer_RawAlarm,RawAlarm_DI_EXCV_LLimit,OperaOpt);
        break;
    case DstInputsOrd_EXCI_HLIMIT:
        ModifyFlagShareBufferDataContent(NULL,CfgOperaType_None,FlagShareBuffer_RawAlarm,RawAlarm_DI_EXCI_HLimit,OperaOpt);
        break;
    case DstInputsOrd_EXCI_LLIMIT:
        ModifyFlagShareBufferDataContent(NULL,CfgOperaType_None,FlagShareBuffer_RawAlarm,RawAlarm_DI_EXCI_LLimit,OperaOpt);
        break;
    case DstInputsOrd_EXCI2_HLIMIT:
        ModifyFlagShareBufferDataContent(NULL,CfgOperaType_None,FlagShareBuffer_RawAlarm,RawAlarm_DI_EXCI2_HLimit,OperaOpt);
        break;
    case DstInputsOrd_EXCI2_LLIMIT:
        ModifyFlagShareBufferDataContent(NULL,CfgOperaType_None,FlagShareBuffer_RawAlarm,RawAlarm_DI_EXCI2_LLimit,OperaOpt);
        break;
    case DstInputsOrd_AUX_IN1:
        ModifyFlagShareBufferDataContent(NULL,CfgOperaType_None,FlagShareBuffer_RawAlarm,RawAlarm_DI_AUX_IN1,OperaOpt);
        break;
    }
    

    return(DEF_TRUE);
}

static uint8_t DigitalInputsWorkLayerHandle(OS_FLAGS os_value, uint8_t InputOrd, uint16_t *TiCount)
{
    uint8_t Status = DEF_FALSE;
    uint8_t InputCtrSta;
    /************************************/
    /* Digital Inputx Workload--Timing */
    if (os_value & OSDSTINFlagsTimingTable[InputOrd])
    {
        /* Check Port */
        if (DigitalInputsScanLayerHandle(InputOrd, TiCount))
            Status |= DigitalInputsActionHandle(InputOrd);
    }
}

static void Init_DigitalInputsRawCloseSta(void)
{
    // uint8_t InputPortSta;
    // InputPortSta = GPIO_ReadInputDataBit(DstInputsCfgTable[DstInputsOrd_EXCV2_HLIMIT].GPIOx, DstInputsCfgTable[DstInputsOrd_EXCV2_HLIMIT].GPIO_Pin);
    // if (InputPortSta == 0)
    //     DigitalInputsRawCloseSta |= 1 << DstInputsOrd_EXCV2_HLIMIT;
    // InputPortSta = GPIO_ReadInputDataBit(DstInputsCfgTable[DstInputsOrd_EXCV2_LLIMIT].GPIOx, DstInputsCfgTable[DstInputsOrd_EXCV2_LLIMIT].GPIO_Pin);
    // if (InputPortSta == 0)
    //     DigitalInputsRawCloseSta |= 1 << DstInputsOrd_EXCV2_LLIMIT;
    // InputPortSta = GPIO_ReadInputDataBit(DstInputsCfgTable[DstInputsOrd_BVOL_HLIMIT].GPIOx, DstInputsCfgTable[DstInputsOrd_BVOL_HLIMIT].GPIO_Pin);
    // if (InputPortSta == 0)
    //     DigitalInputsRawCloseSta |= 1 << DstInputsOrd_BVOL_HLIMIT;
    // InputPortSta = GPIO_ReadInputDataBit(DstInputsCfgTable[DstInputsOrd_BVOL_LLIMIT].GPIOx, DstInputsCfgTable[DstInputsOrd_BVOL_LLIMIT].GPIO_Pin);
    // if (InputPortSta == 0)
    //     DigitalInputsRawCloseSta |= 1 << DstInputsOrd_BVOL_LLIMIT;
    // InputPortSta = GPIO_ReadInputDataBit(DstInputsCfgTable[DstInputsOrd_EXCV_HLIMIT].GPIOx, DstInputsCfgTable[DstInputsOrd_EXCV_HLIMIT].GPIO_Pin);
    // if (InputPortSta == 0)
    //     DigitalInputsRawCloseSta |= 1 << DstInputsOrd_EXCV_HLIMIT;
    // InputPortSta = GPIO_ReadInputDataBit(DstInputsCfgTable[DstInputsOrd_EXCV_LLIMIT].GPIOx, DstInputsCfgTable[DstInputsOrd_EXCV_LLIMIT].GPIO_Pin);
    // if (InputPortSta == 0)
    //     DigitalInputsRawCloseSta |= 1 << DstInputsOrd_EXCV_LLIMIT;
    // InputPortSta = GPIO_ReadInputDataBit(DstInputsCfgTable[DstInputsOrd_EXCI_HLIMIT].GPIOx, DstInputsCfgTable[DstInputsOrd_EXCI_HLIMIT].GPIO_Pin);
    // if (InputPortSta == 0)
    //     DigitalInputsRawCloseSta |= 1 << DstInputsOrd_EXCI_HLIMIT;
    // InputPortSta = GPIO_ReadInputDataBit(DstInputsCfgTable[DstInputsOrd_EXCI_LLIMIT].GPIOx, DstInputsCfgTable[DstInputsOrd_EXCI_LLIMIT].GPIO_Pin);
    // if (InputPortSta == 0)
    //     DigitalInputsRawCloseSta |= 1 << DstInputsOrd_EXCI_LLIMIT;
    // InputPortSta = GPIO_ReadInputDataBit(DstInputsCfgTable[DstInputsOrd_EXCI2_HLIMIT].GPIOx, DstInputsCfgTable[DstInputsOrd_EXCI2_HLIMIT].GPIO_Pin);
    // if (InputPortSta == 0)
    //     DigitalInputsRawCloseSta |= 1 << DstInputsOrd_EXCI2_HLIMIT;
    // InputPortSta = GPIO_ReadInputDataBit(DstInputsCfgTable[DstInputsOrd_EXCI2_LLIMIT].GPIOx, DstInputsCfgTable[DstInputsOrd_EXCI2_LLIMIT].GPIO_Pin);
    // if (InputPortSta == 0)
    //     DigitalInputsRawCloseSta |= 1 << DstInputsOrd_EXCI2_LLIMIT;
    // InputPortSta = GPIO_ReadInputDataBit(DstInputsCfgTable[DstInputsOrd_AUX_IN1].GPIOx, DstInputsCfgTable[DstInputsOrd_AUX_IN1].GPIO_Pin);
    // if (InputPortSta == 0)
    //     DigitalInputsRawCloseSta |= 1 << DstInputsOrd_AUX_IN1;
    // return;
}

/* Digital Inputs Layer Handling */
static uint8_t DigitalInputsLayerHandle(OS_FLAGS os_value)
{
    uint8_t Status = DEF_FALSE;

    Status |= DigitalInputsWorkLayerHandle(os_value, DstInputsOrd_EXCV2_HLIMIT, &DigitalScanTiC_EXCV2_HLIMIT);
    Status |= DigitalInputsWorkLayerHandle(os_value, DstInputsOrd_EXCV2_LLIMIT, &DigitalScanTiC_EXCV2_LLIMIT);
    Status |= DigitalInputsWorkLayerHandle(os_value, DstInputsOrd_BVOL_HLIMIT, &DigitalScanTiC_BVOL_HLIMIT);
    Status |= DigitalInputsWorkLayerHandle(os_value, DstInputsOrd_BVOL_LLIMIT, &DigitalScanTiC_BVOL_LLIMIT);
    Status |= DigitalInputsWorkLayerHandle(os_value, DstInputsOrd_EXCV_HLIMIT, &DigitalScanTiC_EXCV_HLIMIT);
    Status |= DigitalInputsWorkLayerHandle(os_value, DstInputsOrd_EXCV_LLIMIT, &DigitalScanTiC_EXCV_LLIMIT);
    Status |= DigitalInputsWorkLayerHandle(os_value, DstInputsOrd_EXCI_HLIMIT, &DigitalScanTiC_EXCI_HLIMIT);
    Status |= DigitalInputsWorkLayerHandle(os_value, DstInputsOrd_EXCI_LLIMIT, &DigitalScanTiC_EXCI_LLIMIT);
    Status |= DigitalInputsWorkLayerHandle(os_value, DstInputsOrd_EXCI2_HLIMIT, &DigitalScanTiC_EXCI2_HLIMIT);
    Status |= DigitalInputsWorkLayerHandle(os_value, DstInputsOrd_EXCI2_LLIMIT, &DigitalScanTiC_EXCI2_LLIMIT);
    Status |= DigitalInputsWorkLayerHandle(os_value, DstInputsOrd_AUX_IN1, &DigitalScanTiC_AUX_IN1);

    return (Status);
}

/**
 * @brief  Local RAM Reset for DSTIN
 * @param  none
 * @return none.
 * @Caller POR
 * @Note   none.
 */
static void PORLocalRAMReset_DSTIN(void)
{
    DigitalInputsRawCloseSta = 0;

    DigitalScanTiC_EXCV2_HLIMIT = 0;
    DigitalScanTiC_EXCV2_LLIMIT = 0;
    DigitalScanTiC_BVOL_HLIMIT = 0;
    DigitalScanTiC_BVOL_LLIMIT = 0;
    DigitalScanTiC_EXCV_HLIMIT = 0;
    DigitalScanTiC_EXCV_LLIMIT = 0;
    DigitalScanTiC_EXCI_HLIMIT = 0;
    DigitalScanTiC_EXCI_LLIMIT = 0;
    DigitalScanTiC_EXCI2_HLIMIT = 0;
    DigitalScanTiC_EXCI2_LLIMIT = 0;
    DigitalScanTiC_AUX_IN1 = 0;
}
/**
 * @brief  State Control
 * @param  p_arg
 * @return none.
 * @Caller This is a task.
 * @Note   none.
 */
void App_Task_DSTIN(void *p_arg)
{
    uint8_t os_err, Status;
    OS_FLAGS os_value;

    (void)p_arg;

    /* RAM Reset */
    PORLocalRAMReset_DSTIN();
    DstInputsCfg_Init();
    /* Delay */
    OSTimeDlyHMSM(0, 0, 0, 200);
    Init_DigitalInputsRawCloseSta();
    /*  control */
    while (DEF_TRUE)
    {
        /*  Wait for State Update output Flags  */
        os_value = OSFlagPend(App_Flags_DSTIN,
                              OSDSTINFlags_ALL,
                              OS_FLAG_WAIT_SET_ANY + OS_FLAG_CONSUME,
                              0,
                              &os_err);
        if (os_err != OS_ERR_NONE)
            SYS_DebugERROR; /* Error- Only for Debug */

        /*  Workload running */
        Status = DEF_FALSE;
        if (os_value & OSDSTINFlags_DSTINALL)
            Status |= DigitalInputsLayerHandle(os_value);

        /* Inform Workflow Task */
        // if (Status)
        //     SetOSFlagsForNewInform(App_Flags_WORKFLOW, OSWORKFLOWFlags_DstInRequest);
    }
}

#endif